home *** CD-ROM | disk | FTP | other *** search
/ Aminet 50 / Aminet 50 (2002)(GTI - Schatztruhe)[!][Aug 2002].iso / Aminet / text / edit / tecoc-146.lha / srclop.c < prev    next >
C/C++ Source or Header  |  1991-07-05  |  9KB  |  316 lines

  1. /*****************************************************************************
  2.  
  3.     SrcLop()
  4.  
  5. *****************************************************************************/
  6.  
  7. #include "zport.h"        /* define portability identifiers */
  8. #include "tecoc.h"        /* define general identifiers */
  9. #include "defext.h"        /* define external global variables */
  10. #include "deferr.h"        /* define identifiers for error messages */
  11.  
  12. /*****************************************************************************
  13.  
  14.     DoFBFC()
  15.  
  16.     This function is called only by the SrcLop function,  after the
  17. Search function has set up the SBfBeg, SBfEnd, SBfPtr and NArgmt variables.
  18. It is called to handle the special processing needed by the FB and FC
  19. search commands.  The FB and FC commands provide TECO's bounded search
  20. capability.
  21.  
  22. *****************************************************************************/
  23.  
  24. #if USE_PROTOTYPES
  25. static DEFAULT DoFBFC(void);
  26. #endif
  27.  
  28. static DEFAULT DoFBFC()        /* search loop */
  29. {
  30.     ptrdiff_t HowFar;
  31.     ptrdiff_t Shuffl;        /* how far buffer gap is shuffled */
  32.  
  33. #if DEBUGGING
  34.     static char *DbgFNm = "DoFBFC";
  35.     sprintf(DbgSBf,"MArgmt = %ld, NArgmt = %ld", MArgmt, NArgmt);
  36.     DbgFEn(2,DbgFNm,DbgSBf);
  37. #endif
  38.  
  39.     Shuffl = 0;
  40.     if (CmdMod & MARGIS) {            /* if it's m,nFB or m,nFC */
  41.  
  42. /*
  43.  * Call GetAra to convert m and n into addresses.  A side effect of the call
  44.  * to GetAra is that MArgmt and NArgmt are sorted so that MArgmt is less than
  45.  * NArgmt.  We need to know the original order,  so set an indicator variable
  46.  * before calling GetAra.
  47.  */
  48.  
  49.     SIncrm = (MArgmt < NArgmt) ? 1 : -1;
  50.     if (GetAra() == FAILURE) {
  51.         DBGFEX(2,DbgFNm,"FAILURE, GetAra() failed");
  52.         return FAILURE;
  53.     }
  54.  
  55. /*
  56.  * If the edit buffer gap falls between m and n,  we need to shuffle part of
  57.  * the edit buffer to make the m,n area contiguous.  The gap is shuffled so
  58.  * that it is before the m,n area,  so that if part of the match string lies
  59.  * beyond the n boundary,  it can still be matched.
  60.  */
  61.  
  62.     if ((AraBeg < GapBeg) && (AraEnd > GapEnd)) {
  63.         Shuffl = AraEnd - GapEnd;
  64.         GapBeg -= Shuffl;
  65.         GapEnd -= Shuffl;
  66.         MEMMOVE(GapEnd+1, GapBeg, (SIZE_T)Shuffl);
  67.     }
  68.  
  69. /*
  70.  * set the variables for the call to SSerch
  71.  */
  72.  
  73.     if (SIncrm == 1) {        /* forward search */
  74.         EBPtr1 = GapEnd + 1;
  75.         EndSAr = AraEnd;
  76.     } else {            /* else backward search */
  77.         EBPtr1 = AraEnd;
  78.         EndSAr = GapEnd + 1;
  79.     }
  80.     RhtSid = EBfEnd;
  81.     } else {                /* else it's nFB or nFC */
  82.     if (NArgmt > 0) {        /* forward search */
  83.         SIncrm = 1;
  84.         EBPtr1 = GapEnd + 1;
  85.         EndSAr = GapEnd + Ln2Chr(NArgmt);
  86.         RhtSid = EBfEnd;
  87.     } else {            /* else backward search */
  88.         SIncrm = -1;
  89.         EBPtr1 = GapBeg - 1;
  90.         EndSAr = GapBeg + Ln2Chr(NArgmt);
  91.         RhtSid = GapBeg - 1;
  92.     }
  93.     }
  94.  
  95.     if (SSerch() == FAILURE) {
  96.     DBGFEX(2,DbgFNm,"FAILURE, SSerch() failed");
  97.     return FAILURE;
  98.     }
  99.  
  100. /*
  101.  * If the search succeeded,  position the gap to the end of the found string.
  102.  */
  103.  
  104.     if (Matchd) {                /* if search succeeded */
  105.     if (SIncrm == 1) {            /* if forward search */
  106.         HowFar = EBPtr2 - GapEnd;
  107.         MEMMOVE(GapBeg, GapEnd+1, (SIZE_T)HowFar);
  108.         GapBeg += HowFar;
  109.         GapEnd += HowFar;
  110.     } else {
  111.         HowFar = (GapBeg-1) - EBPtr2;
  112.         GapBeg -= HowFar;
  113.         GapEnd -= HowFar;
  114.         MEMMOVE(GapEnd+1, GapBeg, (SIZE_T)HowFar);
  115.     }
  116.     } else {                    /* else search failed */
  117.  
  118. /*
  119.  * If the edit buffer gap was shuffled earlier (because the gap fell into the
  120.  * m,n area),  then we need to reverse shuffle it to leave things as they
  121.  * were.
  122.  */
  123.  
  124.     if (Shuffl != 0) {        /* if buffer was shuffled */
  125.         MEMMOVE(GapBeg, GapEnd+1, (SIZE_T)Shuffl);
  126.         GapBeg += Shuffl;
  127.         GapEnd += Shuffl;
  128.     }
  129.     }
  130. #if DEBUGGING
  131.     sprintf(DbgSBf,"SUCCESS, Matchd = %s", (Matchd) ? "TRUE" : "FALSE");
  132.     DbgFEx(2,DbgFNm,DbgSBf);
  133. #endif
  134.     return SUCCESS;
  135. }
  136.  
  137.  
  138.  
  139. /*****************************************************************************
  140.  
  141.     SrcLop()
  142.  
  143.     This function is called by the Search function only,  after the
  144. Search function has set up the search string buffer (SBfBeg, SBfEnd, SBfPtr)
  145. and the iteration count (NArgmt).  It sets up the edit buffer bounds for the
  146. search (EBPtr1, EndSAr) and direction indicator (SIncrm) and then calls
  147. the SSerch function.  One way to describe this function is that it handles
  148. the numeric arguments of all search commands by handling m,n arguments or
  149. actually doing the loop for n arguments.
  150.  
  151. *****************************************************************************/
  152.  
  153. DEFAULT SrcLop()        /* search loop */
  154. {
  155.     ptrdiff_t    HowFar;
  156.  
  157. #if DEBUGGING
  158.     static char *DbgFNm = "SrcLop";
  159.     sprintf(DbgSBf,"search string SBf = \"%.*s\"",
  160.         (int)(SBfPtr-SBfBeg), SBfBeg);
  161.     DbgFEn(2,DbgFNm,DbgSBf);
  162. #endif
  163.  
  164.     if (SrcTyp == FB_SEARCH) {        /* if it's FB or FC */
  165.     DBGFEX(2,DbgFNm,"returning DoFBFC()");
  166.     return DoFBFC();
  167.     }
  168.  
  169. /*
  170.  * It's not an FB or FC search.  The FB and FC commands are the only ones
  171.  * which can be preceded by an m,n argument pair.  Other search commands
  172.  * can be preceded only by an iteration count.
  173.  */
  174.  
  175.     if (NArgmt > 0) {            /* if forwards search */
  176.     SIncrm = 1;
  177.     EBPtr1 = GapEnd;
  178.     EndSAr = RhtSid = EBfEnd;
  179.     do {
  180.         EBPtr1++;
  181.         if (SSerch() == FAILURE) {
  182.         DBGFEX(2,DbgFNm,"FAILURE, SSerch() failed");
  183.         return FAILURE;
  184.         }
  185.  
  186.         if (Matchd) {            /* if search succeeded */
  187.         --NArgmt;
  188.         if ((EdFlag & ED_DOT_BY_ONE) == 0)
  189.             EBPtr1 = EBPtr2;        /* skip found string */
  190.         } else {                /* else search failed */
  191.         switch (SrcTyp) {
  192.             case S_SEARCH:
  193.             case FK_SEARCH:
  194.             NArgmt = 0;        /* exit loop */
  195.             break;
  196.  
  197.             case N_SEARCH:
  198.             if (IsEofI[CurInp]) {
  199.                 if (WrPage(CurOut,EBfBeg,
  200.                     EBfEnd,FFPage) == FAILURE) {
  201.                 DBGFEX(2,DbgFNm,"FAILURE, WrPage() failed");
  202.                 return FAILURE;
  203.                 }
  204.                 GapBeg = EBfBeg;    /* clear the.. */
  205.                 GapEnd = EBfEnd;    /* ..edit buffer */
  206.                 NArgmt = 0;        /* exit loop */
  207.             } else {        /* else not end-of-file */
  208.                 if (SinglP() == FAILURE) {
  209.                 DBGFEX(2,DbgFNm,"FAILURE, SinglP() failed");
  210.                 return FAILURE;
  211.                 }
  212.                 EBPtr1 = GapEnd + 1;
  213.                 EndSAr = RhtSid = EBfEnd;
  214.             }
  215.             break;
  216.             case U_SEARCH:
  217.             if (((EdFlag & ED_YANK_OK) == 0) &&
  218.                 (IsOpnO[CurOut]) &&
  219.                 ((GapBeg != EBfBeg) || (GapEnd != EBfEnd))) {
  220.                 ErrMsg(ERR_YCA);
  221.                 DBGFEX(2,DbgFNm,"FAILURE");
  222.                 return FAILURE;
  223.             }
  224.             /* FALL THROUGH */
  225.             case E_SEARCH:
  226.             GapBeg = EBfBeg;        /* clear the... */
  227.             GapEnd = EBfEnd;        /* ...edit buffer */
  228.             if (IsEofI[CurInp]) {        /* if end-of-file */
  229.                 NArgmt = 0;            /* exit loop */
  230.             } else {
  231.                if (RdPage() == FAILURE) {
  232.                 DBGFEX(2,DbgFNm,"FAILURE");
  233.                 return FAILURE;
  234.                 }
  235.                 EBPtr1 = GapEnd + 1;
  236.                 EndSAr = RhtSid = EBfEnd;
  237.             }
  238.         }                /* end of switch */
  239.         }
  240.     } while (NArgmt > 0);
  241.     } else {                    /* else backwards search */
  242.     SIncrm = -1;
  243.     EBPtr1 = RhtSid = GapBeg;        /* start point */
  244.     RhtSid--;
  245.     EndSAr = EBfBeg;            /* end point */
  246.     do {
  247.         EBPtr1--;
  248.         if (SSerch() == FAILURE) {
  249.         DBGFEX(2,DbgFNm,"FAILURE, SSerch() failed");
  250.         return FAILURE;
  251.         }
  252.  
  253.         if (Matchd) {
  254.         ++NArgmt;
  255.         } else {
  256.         if ((SrcTyp==S_SEARCH) || (SrcTyp==FK_SEARCH)) {
  257.             break;
  258.         } else {
  259.             DBGFEX(2,DbgFNm,"ExeNYI()");
  260.             return ExeNYI();
  261.         }
  262.         }
  263.     } while (NArgmt < 0);
  264.     }
  265.  
  266. /* The next block of code deals with what happens to the edit buffer after
  267.  * the search.  There are three possibilities:
  268.  *
  269.  *    if the search was successful
  270.  *        if it's an FK command
  271.  *            delete spanned characters
  272.  *        else
  273.  *            move to after the found string
  274.  *    else
  275.  *        move to the start of the edit buffer
  276.  *
  277.  */
  278.  
  279.     if (Matchd) {                /* if search succeeded */
  280.     if (SrcTyp == FK_SEARCH) {        /* if FK command */
  281.         if (SIncrm == 1) {            /* if forward search */
  282.         GapEnd = EBPtr2;        /* delete */
  283.         } else {                /* else backward */
  284.         GapBeg = EBPtr1;        /* delete */
  285.         if (EBPtr2 > GapEnd)
  286.             GapEnd = EBPtr2;
  287.         }
  288.     } else {                /* else not FK */
  289.         if ((SIncrm == 1) || (EBPtr2 > GapEnd)) {
  290.         HowFar = EBPtr2 - GapEnd;
  291.         MEMMOVE(GapBeg, GapEnd+1, (SIZE_T)HowFar);
  292.         GapBeg += HowFar;
  293.         GapEnd += HowFar;
  294.         } else {
  295.         HowFar = (GapBeg-1) - EBPtr2;
  296.         GapBeg -= HowFar;
  297.         GapEnd -= HowFar;
  298.         MEMMOVE(GapEnd+1, GapBeg, (SIZE_T)HowFar);
  299.         }
  300.     }
  301.     } else {                    /* else search failed */
  302.     if ((EdFlag & ED_PRES_DOT) == 0) {    /* if don't preserve dot */
  303.         HowFar = GapBeg - EBfBeg;
  304.         GapBeg -= HowFar;
  305.         GapEnd -= HowFar;
  306.         MEMMOVE(GapEnd+1, GapBeg, (SIZE_T)HowFar);
  307.     }
  308.     }
  309.  
  310. #if DEBUGGING
  311.     sprintf(DbgSBf,"SUCCESS, Matchd = %s", (Matchd) ? "TRUE" : "FALSE");
  312.     DbgFEx(2,DbgFNm,DbgSBf);
  313. #endif
  314.     return SUCCESS;
  315. }
  316.